﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace XTYAPI.PLC
{
    /// <summary>
    /// Float类型转换库
    /// </summary>
    public class FloatLib
    {
        #region 字节数组中截取转成浮点型
        /// <summary>
        /// 将字节数组中某4个字节转换成Float类型
        /// </summary>
        /// <param name="source"></param>
        /// <param name="start"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static float GetFloatFromByteArray(byte[] source, int start = 0, DataFormat type = DataFormat.ABCD)
        {
            byte[] result = ByteArrayLib.Get4ByteArray(source, start, type);
            if (result != null)
            {
                return BitConverter.ToSingle(result, 0);
            }
            else
            {
                return 0.0f;
            }
        }
        #endregion

        #region 将字节数组中截取转成浮点型数组
        /// <summary>
        /// 将字节数组转换成Float数组
        /// </summary>
        /// <param name="source"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static float[] GetFloatArrayFromByteArray(byte[] source, DataFormat type = DataFormat.ABCD)
        {
            float[] values = new float[source.Length / 4];

            for (int i = 0; i < source.Length / 4; i++)
            {
                values[i] = GetFloatFromByteArray(source, 4 * i, type);
            }

            return values;
        }
        #endregion

        #region 将字符串转换成浮点型数组
        /// <summary>
        /// 将Float字符串转换成单精度浮点型数组
        /// </summary>
        /// <param name="val">Float字符串</param>
        /// <returns>单精度浮点型数组</returns>
        public static float[] GetFloatArrayFromString(string val)
        {
            List<float> Result = new List<float>();
            if (val.Contains(' '))
            {
                string[] str = Regex.Split(val, "\\s+", RegexOptions.IgnoreCase);

                foreach (var item in str)
                {
                    Result.Add(Convert.ToSingle(item));
                }
            }
            else
            {
                Result.Add(Convert.ToSingle(val));
            }

            return Result.ToArray();
        }
        #endregion
        #region 将float转化为字节数组
        public static byte[] SetByteArrayFromFloat(double value)
        {
            double wert = (double)value;
            string binString = "";
            byte[] bytes = new byte[4];
            if (wert != 0f)
            {
                if (wert < 0)
                {
                    wert *= -1;
                    binString = "1";
                }
                else
                {
                    binString = "0";
                }
                int exponent = (int)Math.Floor((double)Math.Log(wert) / Math.Log(2.0));
                wert = wert / (Math.Pow(2, exponent)) - 1;

                binString += ValToBinString((byte)(exponent + 127));
                for (int cnt = 1; cnt <= 23; cnt++)
                {
                    if (!(wert - System.Math.Pow(2, -cnt) < 0))
                    {
                        wert = wert - System.Math.Pow(2, -cnt);
                        binString += "1";
                    }
                    else
                        binString += "0";
                }
                bytes[0] = (byte)BinStringToByte(binString.Substring(0, 8));
                bytes[1] = (byte)BinStringToByte(binString.Substring(8, 8));
                bytes[2] = (byte)BinStringToByte(binString.Substring(16, 8));
                bytes[3] = (byte)BinStringToByte(binString.Substring(24, 8));

            }
            else
            {
                bytes[0] = 0;
                bytes[1] = 0;
                bytes[2] = 0;
                bytes[3] = 0;
            }
            return bytes;
        }

        public static byte[] ToByteArray(double[] value)
        {
            ByteArray arr = new ByteArray();
            foreach (double val in value)
                arr.Add(SetByteArrayFromFloat(val));
            return arr.array;
        }
        private static byte? BinStringToByte(string txt)
        {
            int cnt = 0;
            int ret = 0;

            if (txt.Length == 8)
            {
                for (cnt = 7; cnt >= 0; cnt += -1)
                {
                    if (int.Parse(txt.Substring(cnt, 1)) == 1)
                    {
                        ret += (int)(Math.Pow(2, (txt.Length - 1 - cnt)));
                    }
                }
                return (byte)ret;
            }
            return null;
        }
        private static string ValToBinString(byte value)
        {
            string txt = "";

            for (int cnt = 7; cnt >= 0; cnt += -1) //循环8次
            {
                if ((value & (byte)Math.Pow(2, cnt)) > 0)//判断每位的状态
                    txt += "1";   //如果结果大于0意味着 当前二进制位为true
                else
                    txt += "0"; //否则 当前二进制位为false；
            }
            return txt;
        }
        #endregion

    }
}
